Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Allow feature builtins to overwrite existing builtins#13403

Merged
mergify[bot] merged 4 commits into
solana-labs:masterfrom
CriesofCarrots:feature-builtins-overwrite
Nov 5, 2020
Merged

Allow feature builtins to overwrite existing builtins#13403
mergify[bot] merged 4 commits into
solana-labs:masterfrom
CriesofCarrots:feature-builtins-overwrite

Conversation

@CriesofCarrots
Copy link
Copy Markdown
Contributor

@CriesofCarrots CriesofCarrots commented Nov 4, 2020

Problem

Right now, there is no easy way to redeploy a native program (to fix issues, eg). One appealing approach would be to deploy the updated program using feature_builtins, but this requires a way to overwrite an active builtin.

Summary of Changes

  • Add a method to enable overwriting existing builtins
  • Use this method in ensure_feature_builtins to allow a feature_builtin to replace an existing builtin

Needed for #13394

mvines
mvines previously approved these changes Nov 4, 2020
@mergify mergify Bot dismissed mvines’s stale review November 5, 2020 06:01

Pull request has been modified.

@CriesofCarrots CriesofCarrots force-pushed the feature-builtins-overwrite branch 2 times, most recently from 0b7ac24 to 3957cf8 Compare November 5, 2020 06:02
Comment thread runtime/src/bank.rs Outdated
Comment on lines 1746 to 1752
assert!(
!self.is_frozen(),
"Can't change frozen bank by adding not-existing new native program ({}, {}). \
Maybe, inconsistent program activation is detected on snapshot restore?",
name,
program_id
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this assertion to reside immediately before store_account? This assertion is tightly associated to store_account. We can safely assert!(!self.is_frozen()) even if must_replace is true. In general, we must not store_account once frozen in every conceivable situation. But that kind of protection isn't easy to add inside store_account itself, unfortunately. So, we're manually doing this because these activations deal with primitive arrangements with potentinal misbehavior of wracking frozen (snapshot) banks incorrectly.

So, the change hunk could be changed to look like this:

if must_replace {
  assert!(already_genuine_program_exists, ...)
} else if already_genuine_program_exists {
  return;
}

assert!(!self.is_frozen(), ...);
self.store_account(...);

Copy link
Copy Markdown
Contributor Author

@CriesofCarrots CriesofCarrots Nov 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryoqun Moving this assert breaks a bunch of snapshot tests once a NewVersion builtin is added. What do you recommend?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CriesofCarrots Blame me, I completely forget that this fn must retain idempotent of AccountsDB; so more subtle adjustment was needed: 2a9ff42 Hope this commit explains well. If still not sure, please say so. I'll update the in-source comment.

Sorry for confusing you because of my unreadable code. ;)

@ryoqun
Copy link
Copy Markdown
Contributor

ryoqun commented Nov 5, 2020

Thanks for working on this! Good progress. In addition to NewProgram, I think this added NewVersion is decent usecase as well.

Comment thread runtime/src/builtins.rs
@CriesofCarrots CriesofCarrots force-pushed the feature-builtins-overwrite branch from 3957cf8 to b896705 Compare November 5, 2020 06:34
Comment thread runtime/src/bank.rs Outdated
ryoqun
ryoqun previously approved these changes Nov 5, 2020
Copy link
Copy Markdown
Contributor

@ryoqun ryoqun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with a nit

Thanks for improving the native program initialization mechanism!

@CriesofCarrots CriesofCarrots force-pushed the feature-builtins-overwrite branch from b896705 to ec49a46 Compare November 5, 2020 06:50
@mergify mergify Bot dismissed ryoqun’s stale review November 5, 2020 06:50

Pull request has been modified.

@codecov
Copy link
Copy Markdown

codecov Bot commented Nov 5, 2020

Codecov Report

Merging #13403 into master will decrease coverage by 0.0%.
The diff coverage is 90.9%.

@@            Coverage Diff            @@
##           master   #13403     +/-   ##
=========================================
- Coverage    81.9%    81.9%   -0.1%     
=========================================
  Files         376      376             
  Lines       88308    88356     +48     
=========================================
+ Hits        72345    72382     +37     
- Misses      15963    15974     +11     

@ryoqun ryoqun added the automerge Merge this Pull Request automatically once CI passes label Nov 5, 2020
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Nov 5, 2020

automerge label removed due to a CI failure

@mergify mergify Bot removed the automerge Merge this Pull Request automatically once CI passes label Nov 5, 2020
@ryoqun ryoqun added the automerge Merge this Pull Request automatically once CI passes label Nov 5, 2020
@mergify mergify Bot merged commit bc62313 into solana-labs:master Nov 5, 2020
mergify Bot pushed a commit that referenced this pull request Nov 5, 2020
* Allow feature builtins to overwrite existing builtins

* Add feature_builtin ActivationType

* Correctly retain idempotent for replacing case

* Fix test

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
(cherry picked from commit bc62313)

# Conflicts:
#	ledger/src/builtins.rs
#	runtime/src/bank.rs
mergify Bot pushed a commit that referenced this pull request Nov 5, 2020
* Allow feature builtins to overwrite existing builtins

* Add feature_builtin ActivationType

* Correctly retain idempotent for replacing case

* Fix test

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
(cherry picked from commit bc62313)
Comment thread runtime/src/bank.rs
Comment on lines +9362 to +9363
// When replacing native_program, name must change to disambiguate from repeated
// invocations.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should put a comment about this in builtins.rs, since it's critical to know when constructing the name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll sneak that into #13394

mergify Bot added a commit that referenced this pull request Nov 5, 2020
* Allow feature builtins to overwrite existing builtins

* Add feature_builtin ActivationType

* Correctly retain idempotent for replacing case

* Fix test

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
(cherry picked from commit bc62313)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
mergify Bot added a commit that referenced this pull request Nov 5, 2020
…3419)

* Allow feature builtins to overwrite existing builtins (#13403)

* Allow feature builtins to overwrite existing builtins

* Add feature_builtin ActivationType

* Correctly retain idempotent for replacing case

* Fix test

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
(cherry picked from commit bc62313)

# Conflicts:
#	ledger/src/builtins.rs
#	runtime/src/bank.rs

* Fix conflicts

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
@CriesofCarrots CriesofCarrots deleted the feature-builtins-overwrite branch November 18, 2020 00:26
Comment thread runtime/src/bank.rs
Comment on lines +1724 to 1728
let mut existing_genuine_program = self.get_account(&program_id);
if let Some(account) = &mut existing_genuine_program {
if !native_loader::check_id(&account.owner) {
// malicious account is pre-occupying at program_id
// forcibly burn and purge it
Copy link
Copy Markdown
Contributor

@ryoqun ryoqun Dec 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well this logic changes introduced a regression where we could be tricked into skipping to create native program because existing_genuine_program can be set to a bad account and not reset and we enters this match arm returning from this fn: https://github.com/solana-labs/solana/pull/13403/files#diff-ed47b4a0198313377e091bb3957bbbc63d937805426d1b2b6de39d0a50d32a0cR1760

Fixed and test is imrproved at #13884.

Comment thread runtime/src/bank.rs
);

// Add a bogus executable native account, which will be loaded and ignored.
let account = native_loader::create_loadable_account(name);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, when replacing, we must consider the balance of existing program account otherwise we would cause capitalization mismatch if the replaced native program isn't 1 lamports.

Fixed and test added at #13884.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

automerge Merge this Pull Request automatically once CI passes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants